let loginPageUri = "/tattoo/login.html";
let indexPageUri = "/tattoo/index.html";

let appCode = "tattoo";

/**
 * 处理CSRF token的工具类
 * CSRF token是登录时从服务端获取的，会存储在localstorage中
 */
let JwtTokenUtils = {

    /**
     * 检验登录状态，
     * 如果未登录或登录的token过期，将跳转登录页面
     * 如果登录cookie快要过期刷新token
     *
     * 当获取CSRF token的时候，如果当前时间早于token过期时间的一半的时候，将直接从localstorage中获取当亲token
     * 如果当前时间晚于过期时间的一半时，那么将刷新token，获取一个新token，并且把获取到的token缓存到localstorage中
     * 如果当前时间已经晚于过期时间，那么表明token已经过期，将清除localstorage中的token，并且跳转到登录页面
     *
     * tokenExpiration 表示 服务端CSRF的token过期时间,即token将在多少毫秒之后过期,此字段在登录或刷新token的时候由服务端返回
     * 客户端将是这个时间的一半到这个时间这么长时间过期，比如服务端的过期时间为10分钟，那么客户端将会在5-10分钟之内过期
     *
     */
    checkLoginStatus: function () {
        let currentTime = new Date().getTime();

        let currentTokenGetTime = localStorage.getItem("getTokenTime");
        let tokenExpiration = localStorage.getItem("tokenExpiration");

        if (localStorage.getItem("getTokenTime") != null && localStorage.getItem("tokenExpiration") != null) {
            if (currentTime - currentTokenGetTime < tokenExpiration / 2) {
                return true;
            }
            if (currentTime - currentTokenGetTime >= tokenExpiration / 2 && currentTime - currentTokenGetTime < tokenExpiration) {
                this.refreshToken();
                return true;
            }
            return false;
        } else {
            return false;
        }
    },

    /**
     * 获取csrf token
     * 在获取token前先校验登录状态
     *
     * 如果未登录状态或者token已经过期，则判断是否为编辑状态，如果也非编辑状态则跳转登录页面
     * 编辑状态指在sling cms中正在编辑页面
     *
     * @returns {string}
     */
    getBearerHeader: function () {
        if (this.checkLoginStatus()) {
            return "Bearer " + localStorage.getItem("token");
        } else {
            if ($(".sling-cms-mode").text() !== "edit") {
                this.redirectLoginPage();
            }
        }
    },

    /**
     * 跳转登录页
     * 跳转之前清除登录信息token等
     */
    redirectLoginPage() {
        FrontInfoUtils.clearFrontBaseInfo();
        this.clearCSRFToken();
        let currentUrl = location.href.replace(location.origin, "");
        let redirect = encodeURIComponent(currentUrl);
        location.href = loginPageUri + "?redirect=" + redirect;
    },

    /**
     * 刷新csrf token
     */
    refreshToken: function () {
        $.ajax({
            type: 'GET',
            async: false,
            url: "/service/token/refresh",
            headers: {
                Authorization: "Bearer " + localStorage.getItem("token")
            },
            success: function (data) {
                localStorage.setItem("getTokenTime", new Date().getTime().toString());
                localStorage.setItem("tokenExpiration", data.expirationTime);
                localStorage.setItem("token", data.token);
            }
        });
    },

    /**
     * 清除已经登录的token
     */
    clearCSRFToken: function () {
        localStorage.removeItem("token");
        localStorage.removeItem("getTokenTime");
        localStorage.removeItem("tokenExpiration");
    }
};

/**
 * 处理前端权限的工具类
 * @type {{}}
 */
let FrontInfoUtils = {

    renderMenus: function () {
        $.ajax({
            type: 'GET',
            url: "/service/authorize/app/getCurrentUserInfo",
            async: false,
            headers: {
                Authorization: JwtTokenUtils.getBearerHeader()
            },
            success: function (data) {
                localStorage.setItem("currentUserInfo", JSON.stringify(data));
                return data;
            }
        });
    },

    /**
     * 给当前页面所在的菜单字体加粗，并且把当前页面所在的菜单的前辈节点展开
     */
    currentMenuRender: function () {
        let currentPathname = location.pathname;
        let menu = $(".menu-div .menu[uri='" + currentPathname + "']");
        menu.addClass("current");
        menu.parents(".children").addClass("show");
    },

    /**
     * 获取当前用户信息
     */
    getCurrentUserInfo: function () {
        if (localStorage.getItem("currentUserInfo") == null) {
            $.ajax({
                type: 'GET',
                url: "/service/authorize/user/getCurrentUserInfo",
                async: false,
                headers: {
                    Authorization: JwtTokenUtils.getBearerHeader()
                },
                success: function (data) {
                    localStorage.setItem("currentUserInfo", JSON.stringify(data));
                    return data;
                }
            });
        }
        return JSON.parse(localStorage.getItem("currentUserInfo"));
    },

    /**
     * 加载前台权限
     */
    queryCurrentUserFrontPermissions: function (dataStruct) {
        if (localStorage.getItem(appCode + "-" + "currentUserFrontPermissions") == null) {
            $.ajax({
                type: 'GET',
                url: "/service/authorize/app/queryCurrentUserFrontPermissions/" + dataStruct + "/" + appCode,
                async: false,
                headers: {
                    Authorization: JwtTokenUtils.getBearerHeader()
                },
                success: function (data) {
                    localStorage.setItem(appCode + "-" + "currentUserFrontPermissions", JSON.stringify(data));
                    return data;
                }
            });
        }
        return JSON.parse(localStorage.getItem(appCode + "-" + "currentUserFrontPermissions"));
    },

    /**
     * 清除前台基础信息
     */
    clearFrontBaseInfo: function () {
        localStorage.removeItem("currentUserInfo");
        localStorage.removeItem(appCode + "-" + "currentUserFrontPermissions");
    },

    /**
     * 修改密码
     */
    modifyPassword: function () {
        let data = {
            oldPassword: $(".modify-password-window .old-password-value").val(),
            newPassword: $(".modify-password-window .new-password-value").val()
        };
        $.ajax({
            type: 'PUT',
            url: "/service/authorize/user/modifyPassword",
            headers: {
                Authorization: JwtTokenUtils.getBearerHeader()
            },
            data: data,
            success: function () {
                JwtTokenUtils.redirectLoginPage();
            }
        });
    },

    /**
     * 前端权限渲染
     */
    frontMenuPermissionRender() {
        let currentUserInfo = this.getCurrentUserInfo();
        $(".header-div .current-user .user-name").text(currentUserInfo.name);

        let accessControlElements = $(".access-control");

        if (currentUserInfo.username === "admin") {
            accessControlElements.addClass("show");
        }

        let currentUserFrontPermissions = this.queryCurrentUserFrontPermissions(1);

        let menuCodes = [];
        for (let i = 0; i < currentUserFrontPermissions.length; i++) {
            let frontPermission = currentUserFrontPermissions[i];
            let type = frontPermission.type;
            if (type === 0 || type === 1) {
                menuCodes.push(frontPermission.code);
            }
        }

        for (let i = 0; i < accessControlElements.length; i++) {
            let accessControlElement = $(accessControlElements[i]);
            let permissionCode = accessControlElement.attr("permission-code");
            if (menuCodes.indexOf(permissionCode) !== -1) {
                accessControlElement.addClass("show");
                $(accessControlElement.parents(".menu-folder")[0]).addClass("show");
            }
        }
    }
};


/**
 * 分页组件类
 *
 * @type {{}}
 */
let PageComponent = {

    /**
     * 每页显示条数
     */
    size: 10,

    /**
     * 当前页数
     */
    number: 0,

    /**
     * 分页组件容器
     */
    container: null,

    /**
     * 分页组件对象，为jquery dom对象
     */
    htmlDom: null,

    /**
     * 查询参数对象
     */
    queryParam: null,

    /**
     * 执行查询方法
     * 查询方法的入参此分页组件对象
     */
    doQuery: null,

    /**
     * 查询
     *
     *
     * @param {*} queryParam 查询参数
     */
    query: function (queryParam) {
        this.number = 0;
        if (queryParam !== undefined) {
            this.queryParam = queryParam;
        }
        this.doQuery(this);
    },

    /**
     * 刷新数据
     *
     */
    refreshData: function () {
        this.doQuery(this);
    },

    /**
     * 重绘html组件
     *
     *
     * @param {*} pageParams
     */
    rebuildHtmlDom: function (pageParams) {
        let _this = this;

        let pageDiv = _this.htmlDom;
        let totalPages = pageParams.totalPages;
        let number = _this.number;
        let size = _this.size;

        if (totalPages > 0) {
            pageDiv.addClass("show");
        } else {
            pageDiv.removeClass("show");
        }

        let currentShowPageStart = parseInt(pageDiv.attr("show-page-start"));
        let currentShowPageEnd = parseInt(pageDiv.attr("show-page-end"));

        let currentTotalPages = parseInt(pageDiv.attr("total-pages"));
        if (totalPages !== parseInt(currentTotalPages) || (number < currentShowPageStart || number > currentShowPageEnd)) {
            pageDiv.attr("total-pages", totalPages);

            let showPageStart = number - number % size;
            pageDiv.attr("show-page-start", showPageStart);
            let showPageEnd = showPageStart + size;
            pageDiv.attr("show-page-end", showPageEnd);

            let pageNumWrap = pageDiv.find(".page-number-wrap");
            pageNumWrap.empty();
            for (let i = showPageStart; i <= showPageEnd && i < totalPages; i++) {
                let li = $("<li></li>");
                if (i === number) {
                    li.addClass("active");
                }
                let span = $("<span></span>");
                span.text(i + 1);
                li.append(span);
                li.click(function () {
                    _this.number = i;
                    _this.doQuery(_this);
                });
                pageNumWrap.append(li);
            }
        } else {
            let lis = pageDiv.find(".page-number-wrap li");
            lis.removeClass("active");
            $(lis[number - currentShowPageStart]).addClass("active");
        }

        pageDiv.find(".previous-page").off("click").on("click", function () {
            if (number > 0) {
                _this.number = _this.number - 1;
                _this.doQuery(_this);
            }
        });

        pageDiv.find(".next-page").off("click").on("click", function () {
            if (number < totalPages - 1) {
                _this.number = _this.number + 1;
                _this.doQuery(_this);
            }
        });

        pageDiv.find(".first-page").off("click").on("click", function () {
            if (number > 0) {
                _this.number = 0;
                _this.doQuery(_this);
            }
        });

        pageDiv.find(".last-page").off("click").on("click", function () {
            if (number < totalPages - 1) {
                _this.number = totalPages - 1;
                _this.doQuery(_this);
            }
        });

        pageDiv.find(".refresh").off("click").on("click", function () {
            _this.doQuery(_this);
        });
    }

};

/**
 * 分页组件工具类
 *
 * @type {{createPageComponent: (function(*): {})}}
 */
let PageComponentUtils = {
    /**
     * 创建分页组件
     *
     * @param params 分页参数
     */
    createPageComponent: function (params) {
        let pageDiv = $(".front-components .page-div").clone();
        params.container.append(pageDiv);

        let pageComponent = Object.create(PageComponent);
        pageComponent.size = params.size;
        pageComponent.number = params.number;
        pageComponent.queryParam = params.queryParam;
        pageComponent.container = params.container;
        pageComponent.htmlDom = pageDiv;
        pageComponent.doQuery = params.doQuery;

        pageDiv.find("ul li").on("click", function () {
            let size = parseInt($(this).attr("size"));
            pageComponent.size = size;
            pageComponent.doQuery(pageComponent);
        });

        return pageComponent;
    }
};

/**
 * 处理弹窗提示类的工具类
 * @type {{}}
 */
let PromptWindowUtils = {
    /**
     * 删除提示
     * @param promptMsg
     * @param callback
     */
    showDeletePrompt: function (promptMsg, callback) {
        $(".windows .delete-confirm-window").modal('show');
        $(".windows .delete-confirm-window .delete-confirm-content").text(promptMsg);
        $(".windows .delete-confirm-window .delete-confirm-btn").one("click", function () {
            if (typeof callback === "function") {
                callback();
            }
        });
    },

    /**
     * 关闭删除提示窗口
     */
    hideDeletePrompt: function () {
        $(".windows .delete-confirm-window").modal('hide');
    }
};

/**
 * 处理url的工具类
 * @type {{getUrlParam: UrlUtils.getUrlParam}}
 */
let UrlUtils = {

    /**
     * 获取当前url参数
     * @param name
     * @returns {string|null}
     */
    getUrlParam: function (name) {
        let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
        let r = window.location.search.substring(1).match(reg);
        if (r != null) {
            return decodeURIComponent(r[2]);
        }
        return null;
    },

    /**
     * 获取url中的参数
     *
     * @param name 参数名
     * @param url url
     * @returns {string|null}
     */
    getQueryString: function (name, url) {
        let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
        if (typeof url == "undefined" || url == null) {
            url = window.location.search;
        }
        let r = url.substring(1).match(reg);
        if (r != null) {
            return decodeURIComponent(r[2]);
        }
        return null;
    }
};

/**
 * 处理date的工具类
 * @type {{}}
 */
let DateUtils = {

    /**
     * 通过给定的格式化字符串格式化日期
     * @param fmt
     * @returns {void | string | *}
     */
    format: function (date, fmt) {
        let o = {
            "M+": date.getMonth() + 1, //月份
            "d+": date.getDate(), //日
            "h+": date.getHours(), //小时
            "m+": date.getMinutes(), //分
            "s+": date.getSeconds(), //秒
            "q+": Math.floor((date.getMonth() + 3) / 3), //季度
            "S+": date.getMilliseconds() //毫秒
        };
        if (/(y+)/.test(fmt)) {
            fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substring(4 - RegExp.$1.length));
        }
        for (let k in o) {
            if (new RegExp("(" + k + ")").test(fmt)) {
                let rep = "";
                if (RegExp.$1.length === 2) {
                    rep = "00";
                }
                else if (RegExp.$1.length === 3) {
                    rep = "000";
                }
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : ((rep + o[k]).substr(("" + o[k]).length)));
            }
        }
        return fmt;
    }
};

/**
 * 集成工具
 */
let IntegrationUtils = {

    downloadFile: function (url, method, requestData) {
        $.ajax({
            type: method,
            url: url,
            dataType: "binary",
            headers: {
                Authorization: JwtTokenUtils.getBearerHeader()
            },
            xhrFields: {
                responseType: 'blob'
            },
            data: requestData,
            success: function (data, status, xhr) {
                let contentDisposition = xhr.getResponseHeader('Content-Disposition');
                let blob = new Blob([data]);
                let fileName = 'default_filename.ext';
                if (contentDisposition && contentDisposition.indexOf('filename=') !== -1) {
                    let fileNameMatch = contentDisposition.match(/filename="?(.+?)"?(;|$)/);
                    if (fileNameMatch && fileNameMatch.length > 1) {
                        fileName = fileNameMatch[1];
                    }
                }
                let link = document.createElement('a');
                link.href = window.URL.createObjectURL(blob);
                link.download = fileName;
                link.click();
            }
        });
    }

};

$(document).ready(function () {

    if (!JwtTokenUtils.checkLoginStatus() && $(".sling-cms-mode").text() !== "edit") {
        JwtTokenUtils.redirectLoginPage();
    }

    if (JwtTokenUtils.checkLoginStatus()) {
        FrontInfoUtils.frontMenuPermissionRender();
        FrontInfoUtils.currentMenuRender();
    }

    $(".header-div .current-user").mouseover(function () {
        $(".header-div .current-user .user-name-dropdown").addClass("show");
    });

    $(".header-div .current-user").mouseout(function () {
        $(".header-div .current-user .user-name-dropdown").removeClass("show");
    });

    $(".header-div .current-user .logout").click(function () {
        FrontInfoUtils.clearFrontBaseInfo();
        JwtTokenUtils.clearCSRFToken();
        location.href = loginPageUri;
    });

    $(".header-div .logo").click(function () {
        location.href = indexPageUri;
    });

    $(".header-div .open-menu").click(function () {
        if (!$(".menu-div").hasClass("show")) {
            $(".menu-div").addClass("show");
        } else {
            $(".menu-div").removeClass("show");
        }
    });

    $(".main-content,.header-div").click(function (e) {
        if ($(e.target).hasClass("open-menu")) {
            return;
        }
        if ($(".menu-div").hasClass("show")) {
            $(".menu-div").removeClass("show");
        }
    });

    $(".menu-div .menu-item.menu-folder .menu-item-label").click(function () {
        let childrenDiv = $(this).parent().children(".children");
        if (!childrenDiv.hasClass("show")) {
            childrenDiv.addClass("show");
        } else {
            childrenDiv.removeClass("show");
        }
    });

    $(".menu-div .menu-item .menu-item-label").click(function () {
        let parent = $(this).parent();
        if (parent.hasClass("menu")) {
            let uri = parent.attr("uri");
            location.href = uri;
        }
    });

    $(".header-div .current-user .modify-password").click(function () {
        $(".windows .modify-password-window").modal('show');
    });

    $(".modify-password-window .modify-password-confirm-btn").click(function () {
        FrontInfoUtils.modifyPassword();
    });

});